#include "GameBoardRendererThread.h"
#include "GameBoard.h"
#include "GameBoardView.h"
#include <QDebug>

GameBoardRendererThread::GameBoardRendererThread(GameBoard *board, GameBoardView *boardView, unsigned long frameRateInHz)
  : QThread(),
    mBoard(board),
    mBoardView(boardView),
    mFrameRateInHz(frameRateInHz),
    mWidth(0),
    mHeight(0),
    mRenderBoard(true),
    mResizeBoard(false),
    mMousePosition(-1,-1)
{}

void GameBoardRendererThread::resize(const QSize &size)
{
  mWidth = size.width();
  mHeight = size.height();
  mResizeBoard = true;
}

void GameBoardRendererThread::setMousePosition(const QPoint &position)
{
  mMousePosition = position;
}

void GameBoardRendererThread::stop()
{
  mRenderBoard = false;
}

void GameBoardRendererThread::run()
{
  // Initialize GL
  mBoardView->makeCurrent();
  glClearColor(0,0,0,1);
  glAlphaFunc( GL_GREATER, 0.1 );
  glBlendFunc( GL_SRC_ALPHA, GL_ONE );
  resize(mBoardView->size());
  while (mRenderBoard)
  {
    mBoardView->makeCurrent();
    //Resize GL
    if (mResizeBoard)
    {
      glViewport(0,0,mWidth, mHeight);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(-10, 10, -10, 10, -100, 100);
      glMatrixMode(GL_MODELVIEW);
      mResizeBoard = false;
    }
    //Paint GL
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glLoadIdentity();
    gluLookAt(10,10,10,0,0,0,0,1,0);

    //Begin 2D
    glDisable( GL_DEPTH_TEST );
    glMatrixMode( GL_MODELVIEW );
    glPushMatrix();
    glLoadIdentity();
    glMatrixMode( GL_PROJECTION );
    glPushMatrix();
    glLoadIdentity();
    gluOrtho2D( 0, mWidth, 0, mHeight );

    mBoard->lock();
    QList< QList<GameBoard::TILE_COLOR> > tiles = mBoard->getBoard();
    if (tiles.count() > 0 && tiles.at(0).count() > 0)
    {
      int r=0, c=0, tw=mWidth/tiles.count(), th=mHeight/tiles.at(0).count();
      foreach( QList<GameBoard::TILE_COLOR> l, tiles)
      {
        foreach(GameBoard::TILE_COLOR t, l)
        {
          if (t != GameBoard::BLACK)
          {
            if (mMousePosition.x() == c && mMousePosition.y() == r)
            {
              glColor3f(GameBoard::colorFromTileColor(t).lighter().toRgb().redF(),
                        GameBoard::colorFromTileColor(t).lighter().toRgb().greenF(),
                        GameBoard::colorFromTileColor(t).lighter().toRgb().blueF());
            }
            else
            {
              glColor3f(GameBoard::colorFromTileColor(t).toRgb().redF(),
                        GameBoard::colorFromTileColor(t).toRgb().greenF(),
                        GameBoard::colorFromTileColor(t).toRgb().blueF());
            }
            glBegin(GL_QUADS);
              glVertex2i(c*tw, r*th);
              glVertex2i(c*tw+tw, r*th);
              glVertex2i(c*tw+tw, r*th+th);
              glVertex2i(c*tw, r*th+th);
            glEnd();

            glLineWidth(1.0);
            glColor3f(GameBoard::colorFromTileColor(t).darker(125).toRgb().redF(),
                      GameBoard::colorFromTileColor(t).darker(125).toRgb().greenF(),
                      GameBoard::colorFromTileColor(t).darker(125).toRgb().blueF());
            glBegin(GL_LINE_LOOP);
              glVertex2i(c*tw, r*th);
              glVertex2i(c*tw+tw, r*th);
              glVertex2i(c*tw+tw, r*th+th);
              glVertex2i(c*tw, r*th+th);
            glEnd();

            glLineWidth(2.0);
            if (mBoard->isValidPosition(QPoint(c-1,r)) && tiles[c-1][r] != t)
            {
              glColor3i(0,0,0);
              glBegin(GL_LINES);
                glVertex2i(c*tw, r*th);
                glVertex2i(c*tw, r*th+th);
              glEnd();
            }

            if (mBoard->isValidPosition(QPoint(c,r-1)) && tiles[c][r-1] != t)
            {
              glColor3i(0,0,0);
              glBegin(GL_LINES);
                glVertex2i(c*tw, r*th);
                glVertex2i(c*tw+tw, r*th);
              glEnd();
            }
            ++r;
          }
        }
        ++c;
        r=0;
      }
      if (mBoardView->selected())
      {
        glColor3f(1,0,1);
        glLineWidth(10.0);
        glBegin(GL_LINE_LOOP);
          glVertex2i(0,0);
          glVertex2i(tw*tiles.count(),0);
          glVertex2i(tw*tiles.count(),th*tiles[0].count());
          glVertex2i(0,th*tiles[0].count());
        glEnd();
      }
    }
    mBoard->unlock();
    glLineWidth(1.0);
    //End 2D
    glPopMatrix();
    glMatrixMode( GL_MODELVIEW );
    glPopMatrix();
    glEnable( GL_DEPTH_TEST );
    glColor3i(1,1,1);
    mBoardView->swapBuffers();
    msleep(1000.0/mFrameRateInHz);
  }
}
